﻿using System;
using System.Collections;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Web;
using System.Web.UI.WebControls;

using DotNetNuke.Common;
using DotNetNuke.Common.Utilities;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Services.FileSystem;


namespace DotNetNuke.Modules.UserDefinedTable
{



  /// <summary>
  /// support class for UrlDocumentDataType manipulation
  /// </summary>
  internal class UrlDocumentObject
  {



    public enum UrlDocContentTypeEnum
    {
      UrlLink,
      Document
    }



    [StructLayout(LayoutKind.Sequential)]
    protected struct urldocumentInfo
    {
      public UrlDocContentTypeEnum ContentType;
      public string FileID;
      public string OriginalFileName;
      public string Url;
    }


    protected urldocumentInfo _documentInfo;
    protected int _moduleID;
    protected Hashtable _moduleSettings;
    protected PortalSettings _portalSettings;




    protected UrlDocumentObject(int moduleID)
    {
      this._portalSettings = PortalController.GetCurrentPortalSettings();
      ModuleController mc = new ModuleController();
      this._moduleID = moduleID;
      this._moduleSettings = mc.GetModuleSettings(this._moduleID);
    }




    public UrlDocumentObject(int moduleID, string DocMoniker)
      : this(moduleID)
    {
      this._documentInfo = _deserializeDocumentInfo(DocMoniker);
    }




    public UrlDocumentObject(int moduleID, ref FileUpload upload, string strDocumentFolder)
      : this(moduleID)
    {
      string ParentFolderName;

      if (!upload.HasFile)
        throw new ArgumentNullException();

      if (this._portalSettings.ActiveTab.ParentId == this._portalSettings.SuperTabId)
        ParentFolderName = DotNetNuke.Common.Globals.HostMapPath;

      else
        ParentFolderName = this._portalSettings.HomeDirectoryMapPath;

      ParentFolderName = ParentFolderName + strDocumentFolder;
      string strExtension = Path.GetExtension(upload.PostedFile.FileName);
      string SecureFile = Guid.NewGuid().ToString() + strExtension;
      FileSystemUtils.UploadFile(ParentFolderName.Replace("/", @"\"), upload.PostedFile, SecureFile, false);
      FileController fc = new FileController();
      FolderController foC = new FolderController();
      FolderInfo fldr = new FolderInfo();
      fldr = foC.GetFolder(this._portalSettings.PortalId, strDocumentFolder, false);
      DotNetNuke.Services.FileSystem.FileInfo fi = new DotNetNuke.Services.FileSystem.FileInfo();
      fi = fc.GetFile(SecureFile, this._portalSettings.PortalId, fldr.FolderID);

      if (fi == null)
        throw new InvalidOperationException("file not found");

      this._documentInfo = new urldocumentInfo();
      this._documentInfo.ContentType = UrlDocContentTypeEnum.Document;
      this._documentInfo.OriginalFileName = Path.GetFileName(upload.PostedFile.FileName);
      this._documentInfo.FileID = "FileID=" + fi.FileId.ToString();
    }





    protected static urldocumentInfo _deserializeDocumentInfo(string moniker)
    {
      urldocumentInfo retVal = new urldocumentInfo();

      if (moniker.ToLower().StartsWith("http://") ||  moniker.StartsWith("https://"))
      {
        retVal.ContentType = UrlDocContentTypeEnum.UrlLink;
        retVal.Url = moniker;
        return retVal;
      }

      if (!moniker.ToLower().StartsWith("fileid="))
        throw new InvalidOperationException("invalid moniker" + moniker);

      string[] tmp = moniker.Split(new char[] { '|' });
      retVal.ContentType = UrlDocContentTypeEnum.Document;
      retVal.FileID = tmp[0];
      retVal.OriginalFileName = tmp[1];

      return retVal;
    }





    public static string DeleteDocument(ref string DocMoniker)
    {
      FileController fc = new FileController();
      urldocumentInfo docInfo = _deserializeDocumentInfo(DocMoniker);
      DotNetNuke.Services.FileSystem.FileInfo f = fc.GetFileById(int.Parse(UrlUtils.GetParameterValue(docInfo.FileID)), PortalController.GetCurrentPortalSettings().PortalId);

      if (f == null)
        throw new InvalidOperationException("file not found");

      return FileSystemUtils.DeleteFile(f.PhysicalPath, PortalController.GetCurrentPortalSettings());
    }




    public static bool IsUrlValid(string url)
    {
      try
      {
        _deserializeDocumentInfo(url);
      }
      catch (Exception ex)
      {
        return false;
      }

      return true;
    }




    public virtual object ToLink()
    {
      bool bolNewWindow = true;

      if (this._documentInfo.ContentType == UrlDocContentTypeEnum.Document)
      {
        FileController fc = new FileController();
        string strFileId = URLUtil.StripURL(ref this._documentInfo.FileID);
        DotNetNuke.Modules.UserDefinedTable.TokenReplace objTokenReplace = new DotNetNuke.Modules.UserDefinedTable.TokenReplace();
        string strURL = "";
        strURL = this.ToUrl();
        string strDisplayName = this._documentInfo.OriginalFileName;
        return string.Format("<!--{0}--><a href=\"{1}\" {2}>{3}</a>", new object[] { strDisplayName, strURL, (bolNewWindow ? " target=\"_blank\"" : "").ToString(), strDisplayName });
      }

      return string.Format("<!--{0}--><a href=\"{1}\" {2}>{3}</a>", new object[] { "link...", this._documentInfo.Url, (bolNewWindow ? " target=\"_blank\"" : "").ToString(), "link..." });
    }




    /// <summary>
    /// converts existing document into database persistable string (FileID=xx|OriginalFileName)
    /// </summary>
    /// <returns></returns>
    public object ToMoniker()
    {
      if (this._documentInfo.ContentType == UrlDocContentTypeEnum.Document)
        return string.Format("{0}|{1}", this._documentInfo.FileID, this._documentInfo.OriginalFileName);

      return this._documentInfo.Url;
    }




    /// <summary>
    /// converts file on server to valid URL link
    /// </summary>
    /// <returns></returns>
    public virtual string ToUrl()
    {
      if (this._documentInfo.ContentType == UrlDocContentTypeEnum.Document)
        return HttpUtility.HtmlEncode(DotNetNuke.Common.Globals.LinkClick(this._documentInfo.FileID, this._portalSettings.ActiveTab.TabID, this._moduleID, false, Utilities.CBoolN((this._moduleSettings[SettingName.ForceDownload]), false)));

      return this._documentInfo.Url;
    }




    /// <summary>
    /// returns FileID in form FileID=xx, where xx is integer value
    /// </summary>
    public UrlDocContentTypeEnum ContentType
    { get; protected set; }




    /// <summary>
    /// returns FileID in form FileID=xx, where xx is integer value
    /// </summary>
    public string FileID
    { get { return this._documentInfo.FileID; } }



  }
}

